#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
#![feature(extern_types)]
extern crate libc;
use primary::alloc_testing::*;
use primary::set::*;
use primary::compare_pointer::*;
use primary::compare_string::*;
use primary::compare_int::*;
use primary::hash_pointer::*;
use primary::hash_string::*;
use primary::hash_int::*;
extern "C" {
    pub type _Set;
    pub type _SetEntry;
    fn sprintf(_: *mut libc::c_char, _: *const libc::c_char, _: ...) -> libc::c_int;
    fn atoi(__nptr: *const libc::c_char) -> libc::c_int;
    fn __assert_fail(
        __assertion: *const libc::c_char,
        __file: *const libc::c_char,
        __line: libc::c_uint,
        __function: *const libc::c_char,
    ) -> !;
                                                                                            }
#[no_mangle]
pub static mut allocated_values: libc::c_int = 0;
#[no_mangle]
pub extern "C" fn generate_set() -> *mut Set {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut buf: [libc::c_char; 10] = [0; 10];
    let mut i: libc::c_uint = 0;
    let mut value: *mut libc::c_char = std::ptr::null_mut();

    set = set_new(
        Some(string_hash),
        Some(string_equal),
    );

    let set_box = unsafe { Box::from_raw(set) };

    while i < 10000 {
        unsafe {
            sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
            value = alloc_test_strdup(buf.as_mut_ptr());
            set_insert(set, value as SetValue);
            assert_eq!(set_num_entries(set), i.wrapping_add(1));
        }
        i = i.wrapping_add(1);
    }

    unsafe {
        set_register_free_function(set, Some(alloc_test_free));
    }

    set = Box::into_raw(set_box);
    set
}
#[no_mangle]
pub extern "C" fn test_set_new_free() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut i: libc::c_int = 0;
    let mut value: *mut libc::c_int = std::ptr::null_mut();

    set = set_new(
        Some(int_hash),
        Some(int_equal),
    );

    set_register_free_function(
        set,
        Some(alloc_test_free),
    );

    assert!(!set.is_null(), "set != NULL");

    i = 0;
    while i < 10000 {
        value = alloc_test_malloc(std::mem::size_of::<libc::c_int>() as libc::c_ulong) as *mut libc::c_int;
        unsafe { *value = i };
        set_insert(set, value as SetValue);
        i += 1;
    }

    set_free(set);
}
#[no_mangle]
pub extern "C" fn test_set_insert() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut numbers1: [libc::c_int; 6] = [1, 2, 3, 4, 5, 6];
    let mut numbers2: [libc::c_int; 6] = [5, 6, 7, 8, 9, 10];
    let mut i: libc::c_int = 0;

    set = set_new(
        Some(int_hash),
        Some(int_equal),
    );

    let set_box = unsafe { Box::from_raw(set) };

    i = 0;
    while i < 6 {
        unsafe {
            set_insert(
                set,
                &mut *numbers1.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
            );
        }
        i += 1;
    }

    i = 0;
    while i < 6 {
        unsafe {
            set_insert(
                set,
                &mut *numbers2.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
            );
        }
        i += 1;
    }

    assert_eq!(set_num_entries(set), 10);
    set = Box::into_raw(set_box);
    set_free(set);
}
#[no_mangle]
pub extern "C" fn test_set_query() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut buf: [libc::c_char; 10] = [0; 10];
    let mut i: libc::c_int = 0;

    set = generate_set();
    let set_box = unsafe { Box::from_raw(set) };

    i = 0;
    while i < 10000 {
        unsafe {
            sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
        }
        assert_ne!(set_query(set, buf.as_mut_ptr() as SetValue), 0);
        i += 1;
    }

    assert_eq!(set_query(set, b"-1\0" as *const u8 as *const libc::c_char as SetValue), 0);
    assert_eq!(set_query(set, b"100001\0" as *const u8 as *const libc::c_char as SetValue), 0);

    set = Box::into_raw(set_box);
    set_free(set);
}
#[no_mangle]
pub extern "C" fn test_set_remove() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut buf: [libc::c_char; 10] = [0; 10];
    let mut i: libc::c_int = 0;
    let mut num_entries: libc::c_uint = 0;

    set = generate_set();
    let set_box = unsafe { Box::from_raw(set) };
    num_entries = set_num_entries(set);
    assert_eq!(num_entries, 10000, "num_entries == 10000");

    i = 4000;
    while i < 6000 {
        unsafe {
            sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
        }
        assert_ne!(set_query(set, buf.as_mut_ptr() as SetValue), 0, "set_query(set, buf) != 0");
        assert_ne!(set_remove(set, buf.as_mut_ptr() as SetValue), 0, "set_remove(set, buf) != 0");
        assert_eq!(set_num_entries(set), num_entries.wrapping_sub(1), "set_num_entries(set) == num_entries - 1");
        assert_eq!(set_query(set, buf.as_mut_ptr() as SetValue), 0, "set_query(set, buf) == 0");
        num_entries = num_entries.wrapping_sub(1);
        i += 1;
    }

    i = -1000;
    while i < -500 {
        unsafe {
            sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
        }
        assert_eq!(set_remove(set, buf.as_mut_ptr() as SetValue), 0, "set_remove(set, buf) == 0");
        assert_eq!(set_num_entries(set), num_entries, "set_num_entries(set) == num_entries");
        i += 1;
    }

    i = 50000;
    while i < 51000 {
        unsafe {
            sprintf(buf.as_mut_ptr(), b"%i\0" as *const u8 as *const libc::c_char, i);
        }
        assert_eq!(set_remove(set, buf.as_mut_ptr() as SetValue), 0, "set_remove(set, buf) == 0");
        assert_eq!(set_num_entries(set), num_entries, "set_num_entries(set) == num_entries");
        i += 1;
    }

    set = Box::into_raw(set_box);
    set_free(set);
}
#[no_mangle]
pub extern "C" fn test_set_union() {
    let mut numbers1: [libc::c_int; 7] = [1, 2, 3, 4, 5, 6, 7];
    let mut numbers2: [libc::c_int; 7] = [5, 6, 7, 8, 9, 10, 11];
    let mut result: [libc::c_int; 11] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
    let mut i: libc::c_int = 0;
    let mut set1: *mut Set = std::ptr::null_mut();
    let mut set2: *mut Set = std::ptr::null_mut();
    let mut result_set: *mut Set = std::ptr::null_mut();

    unsafe {
        set1 = set_new(
            Some(int_hash),
            Some(int_equal),
        );
    }

    i = 0;
    while i < 7 {
        unsafe {
            set_insert(
                set1,
                &mut *numbers1.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
            );
        }
        i += 1;
    }

    unsafe {
        set2 = set_new(
            Some(int_hash),
            Some(int_equal),
        );
    }

    i = 0;
    while i < 7 {
        unsafe {
            set_insert(
                set2,
                &mut *numbers2.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
            );
        }
        i += 1;
    }

    unsafe {
        result_set = set_union(set1, set2);
    }

    unsafe {
        assert_eq!(set_num_entries(result_set), 11);
    }

    i = 0;
    while i < 11 {
        unsafe {
            assert_ne!(
                set_query(
                    result_set,
                    &mut *result.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
                ),
                0
            );
        }
        i += 1;
    }

    unsafe {
        set_free(result_set);
        set_free(set1);
        set_free(set2);
    }
}
#[no_mangle]
pub extern "C" fn test_set_intersection() {
    let mut numbers1: [libc::c_int; 7] = [1, 2, 3, 4, 5, 6, 7];
    let mut numbers2: [libc::c_int; 7] = [5, 6, 7, 8, 9, 10, 11];
    let mut result: [libc::c_int; 3] = [5, 6, 7];
    let mut i: libc::c_int = 0;
    let mut set1: *mut Set = std::ptr::null_mut();
    let mut set2: *mut Set = std::ptr::null_mut();
    let mut result_set: *mut Set = std::ptr::null_mut();

    unsafe {
        set1 = set_new(
            Some(int_hash),
            Some(int_equal),
        );
        i = 0;
        while i < 7 {
            set_insert(
                set1,
                &mut *numbers1.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
            );
            i += 1;
        }

        set2 = set_new(
            Some(int_hash),
            Some(int_equal),
        );
        i = 0;
        while i < 7 {
            set_insert(
                set2,
                &mut *numbers2.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
            );
            i += 1;
        }

        result_set = set_intersection(set1, set2);
        assert_eq!(set_num_entries(result_set), 3);
        i = 0;
        while i < 3 {
            assert_ne!(
                set_query(
                    result_set,
                    &mut *result.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
                ),
                0
            );
            i += 1;
        }
    }
}
#[no_mangle]
pub extern "C" fn test_set_to_array() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut values: [libc::c_int; 100] = [0; 100];
    let mut array: *mut *mut libc::c_int = std::ptr::null_mut();
    let mut i: libc::c_int = 0;

    set = set_new(
        Some(pointer_hash),
        Some(pointer_equal),
    );

    i = 0;
    while i < 100 {
        values[i as usize] = 1;
        unsafe {
            set_insert(
                set,
                &mut *values.as_mut_ptr().offset(i as isize) as *mut libc::c_int as SetValue,
            );
        }
        i += 1;
    }

    array = set_to_array(set) as *mut *mut libc::c_int;

    i = 0;
    while i < 100 {
        unsafe {
            assert!(**array.offset(i as isize) == 1, "Expected *array[i] == 1");
            **array.offset(i as isize) = 0;
        }
        i += 1;
    }
}
#[no_mangle]
pub extern "C" fn test_set_iterating() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut iterator: SetIterator = _SetIterator {
        set: std::ptr::null_mut(),
        next_entry: std::ptr::null_mut(),
        next_chain: 0,
    };
    let mut count: libc::c_int = 0;

    set = unsafe { generate_set() };

    count = 0;
    unsafe {
        set_iterate(set, &mut iterator);
    }

    while unsafe { set_iter_has_more(&mut iterator) } != 0 {
        unsafe {
            set_iter_next(&mut iterator);
        }
        count += 1;
    }

    assert!(unsafe { set_iter_next(&mut iterator) }.is_null(), "set_iter_next(&iterator) == NULL");
    assert_eq!(count, 10000, "count == 10000");

    unsafe {
        set_free(set);
    }

    set = unsafe {
        set_new(
            Some(int_hash),
            Some(int_equal),
        )
    };

    unsafe {
        set_iterate(set, &mut iterator);
    }
    assert_eq!(unsafe { set_iter_has_more(&mut iterator) }, 0, "set_iter_has_more(&iterator) == 0");

    unsafe {
        set_free(set);
    }
}
#[no_mangle]
pub extern "C" fn test_set_iterating_remove() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut iterator: SetIterator = _SetIterator {
        set: std::ptr::null_mut(),
        next_entry: std::ptr::null_mut(),
        next_chain: 0,
    };
    let mut count: libc::c_int = 0;
    let mut removed: libc::c_uint = 0;
    let mut value: *mut libc::c_char = std::ptr::null_mut();

    set = unsafe { generate_set() };

    count = 0;
    removed = 0;

    unsafe {
        set_iterate(set, &mut iterator);
    }

    while unsafe { set_iter_has_more(&mut iterator) } != 0 {
        value = unsafe { set_iter_next(&mut iterator) } as *mut libc::c_char;
        if unsafe { atoi(value) } % 100 == 0 {
            unsafe {
                set_remove(set, value as SetValue);
            }
            removed = removed.wrapping_add(1);
        }
        count += 1;
    }

    assert_eq!(count, 10000, "count == 10000");
    assert_eq!(removed, 100, "removed == 100");
    assert_eq!(
        unsafe { set_num_entries(set) },
        (10000 as libc::c_uint).wrapping_sub(removed),
        "set_num_entries(set) == 10000 - removed"
    );

    unsafe {
        set_free(set);
    }
}
#[no_mangle]
pub extern "C" fn new_value(mut value: libc::c_int) -> *mut libc::c_int {
    let mut result: *mut libc::c_int = std::ptr::null_mut();

    result = alloc_test_malloc(std::mem::size_of::<libc::c_int>() as libc::c_ulong) as *mut libc::c_int;
    let mut result_box = unsafe { Box::from_raw(result) };
    assert!(!result.is_null(), "Memory allocation failed");
    *result_box = value;
    unsafe { allocated_values += 1; }
    result = Box::into_raw(result_box);

    result
}
#[no_mangle]
pub extern "C" fn free_value(mut value: *mut libc::c_void) {
    let value_box = unsafe { Box::from_raw(value) };
    unsafe {
        alloc_test_free(Box::into_raw(value_box));
        allocated_values -= 1;
        assert!(allocated_values >= 0, "allocated_values cannot be negative");
    }
}
#[no_mangle]
pub extern "C" fn test_set_free_function() {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut i: libc::c_int = 0;
    let mut value: *mut libc::c_int = std::ptr::null_mut();

    set = set_new(
        Some(int_hash),
        Some(int_equal),
    );
    set_register_free_function(
        set,
        Some(free_value),
    );

    unsafe {
        allocated_values = 0;
    }
    i = 0;
    while i < 1000 {
        value = new_value(i);
        set_insert(set, value as SetValue);
        i += 1;
    }
    unsafe {
        assert_eq!(allocated_values, 1000, "allocated_values == 1000");
    }

    i = 500;
    set_remove(set, &mut i as *mut libc::c_int as SetValue);
    unsafe {
        assert_eq!(allocated_values, 999, "allocated_values == 999");
    }

    set_free(set);
    unsafe {
        assert_eq!(allocated_values, 0, "allocated_values == 0");
    }
}
#[no_mangle]
pub unsafe extern "C" fn test_set_out_of_memory() {}
